/******************************************************************************* 
  Copyright (C), 1988-2020, zeno Tech. Co., Ltd.
  Description:   AENC模块  
  Function List:     
  History:
    <wangmc -- 2014-12-10>  创建
*******************************************************************************/ 
/*=============================================================================
                                 Includes                                  
 =============================================================================*/
#include "audioPriv.h"
#include "audioFaac.h"

/*=============================================================================
                               Macro Definition
 =============================================================================*/
#define AUDIO_HEAD_LEN 28
#define AUDIO_TAIL_LEN 8

/*=============================================================================
                        Local Structures and Typedef 
 =============================================================================*/
typedef enum
{
    AENC_MAIN_STREAM,                /* 主码流 */
    AENC_SUB_STREAM1,                /* 辅码流1 */
    AENC_SUB_STREAM2,                /* 辅码流2 */
    AENC_SUB_STREAM3,                /* 辅码流3 */
    AENC_TALKBACK_STREAM,            /* 对讲码流 */
    AENC_UNSUPPORT_STREAM,           /* 无效码流 */
} AENC_streamType_t;

/*=============================================================================
                             Extern Variables                                  
=============================================================================*/
extern unsigned long long vdo_get_time();

/*=============================================================================
                             Local Variables                                  
 =============================================================================*/
static int aencStreamMap_s[audioEncStreamNumber] = 
{   
    AENC_MAIN_STREAM, 
    AENC_SUB_STREAM1, 
    AENC_SUB_STREAM2,
    AENC_SUB_STREAM3,
    AENC_TALKBACK_STREAM,
};

/*=============================================================================
                             Function Definition                                  
 =============================================================================*/
/*******************************************************************************
  Function:     AENC_DmaCopy
  Description:  使用 DMA 复制编码数据,若函数指针为空表示不支持DMA拷贝。
  Input:        - pThiz: 视频编码接口指针
                - pDst: 目标内存地址
                - pSrc: 源数据内存地址，这个是从 getPacket 中取得的地址
                - len:  源数据长度
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_DmaCopy(struct AudioEncoder *pThiz, 
                                    void* pDst, 
                                    void* pSrc, 
                                    unsigned int len)
{
    //memcpy(pDst, pSrc, len);
    return 0;
}

/*******************************************************************************
  Function:     AENC_GetCaps
  Description:  得到音频编码支持的特性。
  Input:        - pThiz: 视频编码接口指针
  Output:       - pCaps: 指向音频编码特性结构AudioEncCaps的指针。
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_GetCaps(struct AudioEncoder *pThiz, AudioEncCaps * pCaps)
{  
    return 0;
}

/*******************************************************************************
  Function:     AENC_GetCaps
  Description:  获取音频编码支持的格式列表，
                应用层必须从支持的列表中选择一项作为setFormat接口的输入参数。
  Input:        - pThiz: 视频编码接口指针
  Output:       - pFormats: 结构AudioEncFormat数组,支持的格式数目用
                    AudioEncCaps::formatCount表示。每个AudioEncFormat结构中的
                    type、frequency、depth参数表示一个有效的编码参数组合，
                    其他参数忽略。
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_GetFormatCaps(struct AudioEncoder *pThiz, 
                                    AudioEncFormat *pFormats)
{
    return 0;
}



/*******************************************************************************
  Function:     ADEC_RecordData
  Description:  底层录音
  Input:        - pEncCtl: 编码通道控制结构体指针
                - pBuf: 音频数据缓存
                - len: 音频数据长度
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_RecordData(AENC_ctl_t *pAencCtl, char *pBuf, unsigned int len)
{
    return 0;
}

/*******************************************************************************
  Function:     AENC_SetVolume
  Description:  设置音频编码的音量。
  Input:        - pThiz: 视频编码接口指针
                - volume: 音量，取值0-100。
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_SetVolume(struct AudioEncoder *pThiz, int volume)
{  
    return 0;
}

/*******************************************************************************
  Function:     AEC_SetVqeAttr
  Description:  设置音质增强
  Input:        - pThiz: 视频编码接口指针
                - pVqeAttr: 音质增强属性
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AEC_SetVqeAttr(struct AudioEncoder *pThiz, AudioVqeAttr *pVqeAttr)
{
    return 0;
}
static int AENC_SendPacketToAo(struct AudioEncoder *pThiz, 
                                    char *pData, int len)
{
#if 0
    MEDIA_BUFFER pstLineOutData = NULL;
    AENC_ctl_t *pAencCtl;
    int ret = 0;
    int u32ReadSize = len;

    pAencCtl = (AENC_ctl_t *)pThiz->priv;
    if (NULL == pAencCtl)
    {
        LOG_PrintError("AudioEncoder isn't initialized\n");
        return -1;
    }
    pstLineOutData = RK_MPI_MB_CreateAudioBuffer(u32ReadSize, RK_FALSE);
    if (!pstLineOutData) {
        printf("ERROR: create audio buffer\n");
        ret = -1;
        goto release_buffer;
    }
    memcpy(RK_MPI_MB_GetPtr(pstLineOutData), pData, u32ReadSize);
    RK_MPI_MB_SetSize(pstLineOutData, u32ReadSize);
    ret = RK_MPI_SYS_SendMediaBuffer(RK_ID_AO, pAencCtl->aiChn, pstLineOutData);
    if (ret) {
        printf("ERROR: RK_MPI_SYS_SendMediaBuffer failed! ret = %d\n", ret);
        ret = -1;
        goto release_buffer;
    }
    //HexPrint("audio", pAudioEncPacket->buffer + AENC_FRAME_LEN, 64);
    //FILE_write("/root/lineout.pcm", pAudioEncPacket->buffer + AENC_FRAME_LEN, AENC_FRAME_LEN);
release_buffer:
    ret = RK_MPI_MB_ReleaseBuffer(pstLineOutData);
    if (0 != ret)
    {
        LOG_PrintError("RK_MPI_MB_ReleaseBuffer fail chn %d ret 0x%x\n\n",
                        0, ret);
        ret = -1;
    }
    pstLineOutData = NULL;
    return ret;
#endif
    return 0;
}

/*******************************************************************************
  Function:     AENC_AddRef
  Description:  增加接口引用
  Input:        - pThiz: 视频编码接口指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_AddRef(struct AudioEncoder *pThiz)
{
    AENC_ctl_t *pAencCtl;

    if (!pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pAencCtl = (AENC_ctl_t *)pThiz->priv;
    if (!pAencCtl)
    {
        LOG_PrintError("AudioEncoder isn't initialized\n");
        return -1;
    }
    
    pthread_mutex_lock(&audioCtl_g.audioMutex);

    pAencCtl->refCount++;
    
    pthread_mutex_unlock(&audioCtl_g.audioMutex);
    
    return 0;
}

/*******************************************************************************
  Function:     AENC_Release
  Description:  释放接口
  Input:        - pThiz: 视频编码接口指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_Release(struct AudioEncoder *pThiz)
{
    int ret = 0;
    AENC_ctl_t *pAencCtl;

    if (!pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pAencCtl = (AENC_ctl_t *)pThiz->priv;
    if (!pAencCtl)
    {
        LOG_PrintError("AudioEncoder isn't initialized\n");
        return -1;
    }
    
    pthread_mutex_lock(&audioCtl_g.audioMutex);

    if (pAencCtl->refCount > 1)
    {
        pAencCtl->refCount--;
        goto unlock_mutex;
    }

    pAencCtl->refCount = 0;

    audioCtl_g.pEncCtls[pAencCtl->streamId] = NULL;

    free(pAencCtl);
    
unlock_mutex:       
    pthread_mutex_unlock(&audioCtl_g.audioMutex);
    return ret;
}
/*******************************************************************************
  Function:     AENC_GetCfg
  Description:  获取音频编码参数
  Input:        - pAencCtl: 音频编码通道控制结构体指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_GetCfg(AENC_ctl_t *pAencCtl)
{
    pAencCtl->aencFormat.type = audioEncAAC;
    pAencCtl->aencFormat.pack = audioEncPackTypeADTS;
    pAencCtl->aencFormat.frequency = 48000;
    pAencCtl->aencFormat.channelNum = 1;
    pAencCtl->aencFormat.depth = 16;
    
    return 0;
}

/*******************************************************************************
  Function:     AENC_DeinitList
  Description:  情况队列
  Input:        - pAencCtl: 音频编码通道控制结构体指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_DeinitList(AENC_ctl_t *pAencCtl)
{
    ACOMM_listInfo_t *pListFrame;

    pthread_mutex_lock(&pAencCtl->aencBufLock);
    
    while (!list_empty(&pAencCtl->fullBuf))
    {
        pListFrame = list_first_entry(&pAencCtl->fullBuf, ACOMM_listInfo_t, list);
        list_del(&pListFrame->list);
        list_add_tail(&pListFrame->list, &pAencCtl->emptyBuf);
    }

    pthread_mutex_unlock(&pAencCtl->aencBufLock);

    LOG_PrintError("AENC_DeinitList SUCCESS\n");
            
    return 0;
}


/*******************************************************************************
  Function:     AENC_SetFormat
  Description:  设置音频数据编码的格式。
  Input:        - pThiz: 视频编码接口指针
  Output:       - pFormat: 指向音频编码格式结构AudioEncFormat的指针。
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_SetFormat(struct AudioEncoder *pThiz, AudioEncFormat *pFormat)
{ 
    if (!pThiz || !pFormat)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }
    
    int ret = 0;
    AENC_ctl_t * pAencCtl = (AENC_ctl_t *)pThiz->priv;
    if (!pAencCtl)
    {
        LOG_PrintError("AudioEncoder isn't initialized\n");
        return -1;
    }
    
    pthread_mutex_lock(&audioCtl_g.audioMutex);

    if (pAencCtl->aencState == AENC_STREAM_START)
    {
        LOG_PrintError("aenc channel %d is running!\n", pAencCtl->aencChn);
        ret = -1;
        goto mutex_unlock;
    }

    ///AAC编码处理
    if(pFormat->type == audioEncAAC)
    {
        AAC_audioCfg_t pAacCfg = {0};
        pAacCfg.sampleRate = pFormat->frequency;
        pAacCfg.channels = pFormat->channelNum;
        pAacCfg.bitWidth= pFormat->depth;
        pAacCfg.outputFormat = pFormat->pack;

        if(!pAencCtl->pAacCtl)
        {
            pAencCtl->pAacCtl = AAC_EncCreat(&pAacCfg);
            if (!pAencCtl->pAacCtl)
            {
                LOG_PrintError("AAC_EncCreat failed\n");
                ret = -1;
                goto mutex_unlock;
            }
        }

        ret = AAC_EncSetFormat(pAencCtl->pAacCtl, &pAacCfg);//暂不支持动态更新
        if (ret)
        {
            LOG_PrintError("AAC_EncSetFormat failed!\n");
            ret = -1;
            goto mutex_unlock;
        }

       
    }

    memcpy(&pAencCtl->aencFormat, pFormat, sizeof(AudioEncFormat));

    LOG_PrintInfo("AAC_EncSetFormat aencChn:%d, pFormat->frequency:%d, pFormat->channelNum:%d,pFormat->pack:%d!\n", pAencCtl->aencChn, pFormat->frequency,pFormat->channelNum,pFormat->pack);
    
mutex_unlock:       
    pthread_mutex_unlock(&audioCtl_g.audioMutex);

    return ret;
}

/*******************************************************************************
  Function:     AENC_Start
  Description:  开始音频编码
  Input:        - pThiz: 视频编码接口指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_Start(struct AudioEncoder *pThiz)
{
    int ret = 0;
    AENC_ctl_t *pAencCtl;
    
    if (!pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pAencCtl = (AENC_ctl_t *)pThiz->priv;
    if (!pAencCtl)
    {
        LOG_PrintError("AudioEncoder isn't initialized\n");
        return -1;
    }
    
    pthread_mutex_lock(&audioCtl_g.audioMutex);
    
    if (pAencCtl->aencState == AENC_STREAM_START)
    {
        LOG_PrintError("aenc channel %d is running!\n", pAencCtl->aencChn);
        goto mutex_unlock;
    }

    ///AAC编码处理
    if(pAencCtl->aencFormat.type == audioEncAAC)
    {
        if(!pAencCtl->pAacCtl)
        {
            LOG_PrintError("aacenc channel %d is not creeat!\n", pAencCtl->aencChn);
            ret = -1;
            goto mutex_unlock;
        }
        
        AAC_EncStart(pAencCtl->pAacCtl);        
    }
	
    pAencCtl->aencState = AENC_STREAM_START;

    LOG_PrintInfo("AENC_Start pAencCtl->aencChn:%d success\n", pAencCtl->aencChn);
    
mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.audioMutex);
    
    return ret;
}


/*******************************************************************************
  Function:     AENC_Stop
  Description:  停止音频编码
  Input:        - pThiz: 视频编码接口指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_Stop(struct AudioEncoder *pThiz)
{
    int ret = 0;
    AENC_ctl_t *pAencCtl;
    
    if (NULL == pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pAencCtl = (AENC_ctl_t *)pThiz->priv;
    if (!pAencCtl)
    {
        LOG_PrintError("AudioEncoder isn't initialized\n");
        return -1;
    }

    pthread_mutex_lock(&audioCtl_g.audioMutex);

    if (pAencCtl->aencState == AENC_STREAM_STOP)
    {
        LOG_PrintError("aenc channel %d is already stop!\n", pAencCtl->aencChn);
        goto mutex_unlock;
    }

    ///AAC编码处理
    if(pAencCtl->aencFormat.type == audioEncAAC)
    {
        if(!pAencCtl->pAacCtl)
        {
            LOG_PrintError("aacenc channel %d is not creeat!\n", pAencCtl->aencChn);
            ret = -1;
            goto mutex_unlock;
        }
        
        AAC_EncStop(pAencCtl->pAacCtl);        
    }

    //清空队列
    if(pAencCtl->aencFormat.type == audioEncPCM)
    {
        AENC_DeinitList(pAencCtl);
    }

    pAencCtl->aencState = AENC_STREAM_STOP;

    LOG_PrintInfo("AENC_Stop success\n");

mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.audioMutex);
    return ret;
}

/*******************************************************************************
  Function:     AENC_GetSpecificInfo
  Description:  获取音频编码数据需要的解码信息
  Input:        - pThiz: 视频编码接口指针               
  Output:       - ppBuffer 解码信息裸指针的指针
                - pSize 解码信息长度
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_GetSpecificInfo(struct AudioEncoder *pThiz, char **ppBuffer, unsigned long *pSize)
{
    int ret = 0;
    AENC_ctl_t *pAencCtl;
    
    if (NULL == pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pAencCtl = (AENC_ctl_t *)pThiz->priv;
    if (!pAencCtl)
    {
        LOG_PrintError("AudioEncoder isn't initialized\n");
        return -1;
    }

    pthread_mutex_lock(&audioCtl_g.audioMutex);

    ///AAC编码处理
    if(pAencCtl->aencFormat.type == audioEncAAC)
    {
        if(!pAencCtl->pAacCtl)
        {
            LOG_PrintError("aacenc channel %d is not creeat!\n", pAencCtl->aencChn);
            ret = -1;
            goto mutex_unlock;
        }
        
        ret = AAC_EncGetDecSpecificInfo(pAencCtl->pAacCtl, ppBuffer, pSize);               
    }


mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.audioMutex);
    return ret;
}

/*******************************************************************************
  Function:     AENC_PutAudioRawData
  Description:  开始音频编码
  Input:        - pAencCtl: 视频编码控制指针
                - pBuf: 输入编码裸数据
                - len: 输入裸数据长度
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_PutRawDataUnlock(AENC_ctl_t *pAencCtl, char *pBuf, int len, uint64 pts)
{
    int ret = 0;
    if (!pAencCtl || !pBuf)
    {
        LOG_PrintError("pAencCtl or pbuf is NULL\n");
        return -1;
    }

     //LOG_PrintInfo("AENC_PutRawDataUnlock len2:%d\n", len);
    ///AAC编码处理
    if(pAencCtl->aencFormat.type == audioEncAAC)
    {
        if(!pAencCtl->pAacCtl)
        {
            LOG_PrintError("aacenc channel %d is not running!\n", pAencCtl->aencChn);
            return -1;
        }

        //audio_FILE_Write("wyg/123.pcm", pBuf, len);
        
        ret = AAC_EncSendFrame(pAencCtl->pAacCtl, pBuf, len);
        if (ret)
        {
            LOG_PrintError("ERROR: AAC_EncSendFrame\n");
    		return -1;
        }      
    }
    else if(pAencCtl->aencFormat.type == audioEncPCM)
    {
        ACOMM_listInfo_t *pListFrame = NULL;
        pthread_mutex_lock(&pAencCtl->aencBufLock);
        if(!list_empty(&pAencCtl->emptyBuf))
        {
            pListFrame = list_first_entry(&pAencCtl->emptyBuf, ACOMM_listInfo_t, list);
            list_del(&pListFrame->list);
            pthread_mutex_unlock(&pAencCtl->aencBufLock);
           
            pListFrame->len = len;
            pListFrame->pts = vdo_get_time(); //pts;
            memcpy(pListFrame->pBuf, pBuf, len);

            pthread_mutex_lock(&pAencCtl->aencBufLock);
            list_add_tail(&pListFrame->list, &pAencCtl->fullBuf);
            pthread_mutex_unlock(&pAencCtl->aencBufLock);

            //audio_FILE_Write("wyg/audio_linin_enc.pcm", pBuf, len); 
        }
        else
        {
            pthread_mutex_unlock(&pAencCtl->aencBufLock);
            //LOG_PrintWarn("AENC_PutRawDataUnlock::emptyBuf list is empty!\n");
        }
    }
    
    return ret;
}


/*******************************************************************************
  Function:     AENC_PutAudioRawData
  Description:  开始音频编码
  Input:        - pThiz: 视频编码接口指针
                - pBuf: 输入编码裸数据
                - len: 输入裸数据长度
                - pts: 时间戳
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_PutAudioRawData(struct AudioEncoder *pThiz, char *pBuf, int len,  uint64 pts)
{
	int ret = 0;
	int result = 0;
    AENC_ctl_t *pAencCtl;
    
    if (!pThiz || !pBuf || len <= 0)
    {
        //LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pAencCtl = (AENC_ctl_t *)pThiz->priv;
    if (!pAencCtl)
    {
        LOG_PrintError("AudioEncoder isn't initialized\n");
        return -1;
    }

    pthread_mutex_lock(&audioCtl_g.audioMutex);

    if (pAencCtl->aencState == AENC_STREAM_STOP)
    {
        //LOG_PrintError("aenc channel %d is already stop!\n", pAencCtl->aencChn);
        ret = -1;
        goto mutex_unlock;
    }

    result = AENC_PutRawDataUnlock(pAencCtl, pBuf, len, pts);
    if (result)
    {
        LOG_PrintError("Fail to start channel %d!\n", pAencCtl->aencChn);
        ret = -1;
        goto mutex_unlock;
    }

mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.audioMutex);
    return ret;

}

/*******************************************************************************
  Function:     AENC_GetPacket
  Description:  获取编码数据
  Input:        - pThiz: 视频编码接口指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_GetPacket(struct AudioEncoder *pThiz, 
                                AudioEncPacket *pAudioEncPacket)
{
    int status, ret = 0;
    AENC_ctl_t *pAencCtl;
    int getSize = 0;

    if(!pAudioEncPacket || !(pAudioEncPacket->buffer))
    {
        LOG_PrintError("pAudioEncPacket is error\n");
        return -1;
    }

    if (!pThiz)
    {
        LOG_PrintError("Input parameter is NULL\n");
        return -1;
    }

    pAencCtl = (AENC_ctl_t *)pThiz->priv;
    if (!pAencCtl)
    {
        LOG_PrintError("AudioEncoder isn't initialized\n");
        return -1;
    }

    pthread_mutex_lock(&audioCtl_g.audioMutex);

    if (pAencCtl->aencState == AENC_STREAM_STOP)
    {
        //LOG_PrintError("aenc channel %d is already stop!\n", pAencCtl->aencChn);
        ret = -1;
        goto mutex_unlock;
    }

    //LOG_PrintWarn("pAencCtl->aencFormat.type : %d\n", pAencCtl->aencFormat.type );

    ///AAC编码处理
    if(pAencCtl->aencFormat.type == audioEncAAC)
    {
        if(!pAencCtl->pAacCtl)
        {
            LOG_PrintError("aacenc channel %d is not running!\n", pAencCtl->aencChn);
            ret = -1;
            goto mutex_unlock;
        }

        AAC_aencStream_t aencStream = {0};
        ret = AAC_EncGetStream(pAencCtl->pAacCtl, &aencStream);
    	if (ret || (aencStream.dataSize == 0))
    	{
    		ret = -1;
            goto mutex_unlock;
    	}
    	
    	memcpy(pAudioEncPacket->buffer, aencStream.pData, aencStream.dataSize);
    	pAudioEncPacket->length = aencStream.dataSize;  
    	pAudioEncPacket->pts = aencStream.tvSec * 1000 + aencStream.tvUsec / 1000;    	

        ret = AAC_EncReleaseStream(pAencCtl->pAacCtl, &aencStream);
        if (ret)
        {
            LOG_PrintError("AENC Release Stream chn %d\n", pAencCtl->aencChn);
            ret = -1;
            goto mutex_unlock;
        }
    	
    }     
    else if(pAencCtl->aencFormat.type == audioEncPCM)
    {
        ACOMM_listInfo_t* pListFrame = NULL; 
        
        pthread_mutex_lock(&pAencCtl->aencBufLock);            
        if(!list_empty(&pAencCtl->fullBuf))
        {
            ///get full node from list
            pListFrame = list_first_entry(&pAencCtl->fullBuf, ACOMM_listInfo_t, list);
            list_del(&pListFrame->list);
            pthread_mutex_unlock(&pAencCtl->aencBufLock);

            memcpy(pAudioEncPacket->buffer, pListFrame->pBuf, pListFrame->len);
            pAudioEncPacket->length = pListFrame->len;  
    	    pAudioEncPacket->pts = pListFrame->pts;
            
            ///put empty node to list
            pthread_mutex_lock(&pAencCtl->aencBufLock);    
            list_add_tail(&pListFrame->list, &pAencCtl->emptyBuf);
            pthread_mutex_unlock(&pAencCtl->aencBufLock);

            //LOG_PrintWarn("AENC_GetPacket:: bufLen=%d\n",pListFrame->len);

            //audio_FILE_Write("wyg/audio_linin_enc1.pcm", pAudioEncPacket->buffer, pAudioEncPacket->length); 
        }
        else
        {
            pthread_mutex_unlock(&pAencCtl->aencBufLock);

            //LOG_PrintError("fullBuf is NULL\n");
            ret = -1;
        }
        
    }
       
mutex_unlock:   
    pthread_mutex_unlock(&audioCtl_g.audioMutex);
    return ret;
}

#if 0
static void* AudioTestPutThd(void *parg)
{
    AENC_ctl_t *pAencCtl = (AENC_ctl_t *)parg;
    if (!pAencCtl)
    {
        LOG_PrintError("pAencCtl is NULL\n");
        return NULL;
    }

    MEDIA_BUFFER pstAudioData = NULL;
    int ret = 0;

    while(1)
    {
        if(pAencCtl->aencState == AENC_STREAM_STOP)
        {
            usleep(50*1000);
            continue;
        }

        AI_ctl_t *pAiCtl =  audioCtl_g.pAiCtls[pAencCtl->aencChn];
        if(AI_GetFullFromList(pAiCtl, &pAencCtl->pListPacket) == 0)
        {            
            AENC_PutRawDataUnlock(pAencCtl, pAencCtl->pListPacket.pBuf, pAencCtl->pListPacket.len);


            AI_PutEmptyToList(pAiCtl, &pAencCtl->pListPacket);

            //continue;
        }

        usleep(5*1000);
    
       // FILE_write("/nfsroot/StreamFile/222.pcm", RK_MPI_MB_GetPtr(pstAudioData), len);  
        
    }

    
    return NULL;
    
}

static void* AudioTestGetThd(void *parg)
{
    AENC_ctl_t *pAencCtl = (AENC_ctl_t *)parg;
    if (!pAencCtl)
    {
        LOG_PrintError("pAencCtl is NULL\n");
        return NULL;
    }

    int ret = 0;
    uchar pDataTest[4096] = {0};  
    

    while(1)
    {
        //LOG_PrintError("AAC Encode pAencCtl->aencChn:%d, aencState:%d ,type=%d\n", pAencCtl->aencChn, pAencCtl->aencState, pAencCtl->aencFormat.type);
        
        if(pAencCtl->aencState == AENC_STREAM_STOP)
        {
            usleep(100*1000);
            continue;
        }

        ///AAC编码处理
        if(pAencCtl->aencFormat.type == audioEncAAC)
        {
            if(!pAencCtl->pAacCtl)
            {
                LOG_PrintError("aacenc channel %d is not running!\n", pAencCtl->aencChn);
                ret = -1;
                break;
            }

            //LOG_PrintError("AAC Encode start ...\n");

            AAC_aencStream_t aencStream = {0};
            ret = AAC_EncGetStream(pAencCtl->pAacCtl, &aencStream);
        	if (ret)
        	{
                usleep(5*1000);
                //LOG_PrintError("AAC Encode AAC_EncGetStream failed.\n");
                continue;
        	}

        	LOG_PrintError("AAC Encode len = %d \n", aencStream.dataSize);

        	//FILE_write1("/nfsroot/StreamFile/Linein.aac", aencStream.pData, aencStream.dataSize);   

        #if 0
            ADEC_ctl_t *pAdecCtl =  audioCtl_g.pAdecCtls[pAencCtl->aencChn];
            if(pAdecCtl)
            {
                memset(pDataTest, 0, sizeof(pDataTest));
                memcpy(pDataTest, aencStream.pData, aencStream.dataSize);
                
        	    ADEC_PutPacketTest(pAdecCtl, pDataTest, aencStream.dataSize);
        	}
        #endif
        
        	//LOG_PrintError("AAC Encode end.... \n");
	
        }    
        
    }

    LOG_PrintError("AudioTestGetThd leave\n");
    
    return NULL;
    
}
#endif

/*******************************************************************************
  Function:     AENC_ReleasePacket
  Description:  释放采样数据
  Input:        - pThiz: 视频编码接口指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
static int AENC_ReleasePacket(struct AudioEncoder *pThiz)
{
    return 0;
}


/*******************************************************************************
  Function:     createAudioEncoder
  Description:  创建音频编码通道接口
  Input:        - pAencDesc: 音频编码通道接口参数
  Output:       - ppAudioEncoder: 音频编码通道接口
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int PAL_API createAudioEncoder(AudioEncDesc *pAencDesc, 
                                AudioEncoder **ppAudioEncoder)
{
    int ret = 0, result;
    AudioEncoder *pAudioEncoder;
    unsigned int streamId;
    AENC_ctl_t *pAencCtl;
	
    if ((NULL == pAencDesc) || (NULL == ppAudioEncoder))
    {
        LOG_PrintError("Parameter is NULL!\n");
        return -1;
    }

    streamId = pAencDesc->channel;

    if (streamId >= (AENC_SUPPORT_CHN))
    {
        LOG_PrintError("channel:%d is over AENC_SUPPORT_CHN!\n", pAencDesc->channel);
        return -1;
    }
    
    pthread_mutex_lock(&audioCtl_g.audioMutex);

    pAencCtl = audioCtl_g.pEncCtls[streamId];
    if (pAencCtl)
    {
        LOG_PrintInfo("audio encoder has already been created,"
                       "srcs = %d, channel = %d\n", 
                       (int)pAencDesc->srcs, pAencDesc->channel);
        pAencCtl->refCount++;
        *ppAudioEncoder = &pAencCtl->audioEncoder;
        goto mutex_unlock;
    }

    pAencCtl = (AENC_ctl_t *)malloc(sizeof(AENC_ctl_t));
    if (!pAencCtl)
    {
        LOG_PrintError("There is no enough memory to allocate AudioEncoder!\n");
        ret = -1;
        goto mutex_unlock;
    }
    memset(pAencCtl, 0, sizeof(AENC_ctl_t));

    pAencCtl->aencChn = streamId;
    //pAencCtl->aencStream = pAencDesc->stream;
    pAencCtl->refCount++;

    result = AENC_GetCfg(pAencCtl);
    if (result)
    {
        LOG_PrintError("Fail to get aencode config!\n");
        ret = -1;
        goto free_ctl;
    }

    /*pAencCtl->pAencBuf = (int8 *)malloc(AENC_DATA_MAX_SIZE); 
    if (!pAencCtl->pAencBuf)
    {
        LOG_PrintError("Fail to malloc aenc buf!\n");
        ret = -1;
        goto free_ctl;
    }*/

    ///init list 用来储存混音后pcm数据，方便media层统一获取
    int i;
    INIT_LIST_HEAD(&pAencCtl->emptyBuf);
    INIT_LIST_HEAD(&pAencCtl->fullBuf);
    pthread_mutex_init(&pAencCtl->aencBufLock, NULL);
    for (i = 0; i < 5; i++)
    {
        pAencCtl->listBuf[i].pBuf = (char *)malloc(2*4096); //长度待定
        if (!pAencCtl->listBuf[i].pBuf)
        {
            LOG_PrintError("Fail to malloc!\n");
            ret = -1;
            goto free_ctl;
        }
        pAencCtl->listBuf[i].pts = 0;
        pAencCtl->listBuf[i].len = 0;
	    list_add_tail(&pAencCtl->listBuf[i].list, &pAencCtl->emptyBuf);
	}

    audioCtl_g.pEncCtls[streamId] = pAencCtl;
    
    pAudioEncoder = &pAencCtl->audioEncoder;
    pAudioEncoder->priv = pAencCtl;
    pAudioEncoder->addRef = AENC_AddRef;
    pAudioEncoder->release = AENC_Release;
    pAudioEncoder->dmaCopy = AENC_DmaCopy;
    pAudioEncoder->getCaps = AENC_GetCaps;
    pAudioEncoder->getFormatCaps = AENC_GetFormatCaps;
    pAudioEncoder->setFormat = AENC_SetFormat;
    pAudioEncoder->setVolume = AENC_SetVolume;
    pAudioEncoder->start = AENC_Start;
    pAudioEncoder->stop = AENC_Stop;
    pAudioEncoder->getPacket = AENC_GetPacket;
    pAudioEncoder->releasePacket = AENC_ReleasePacket;
    pAudioEncoder->setVqeAttr = AEC_SetVqeAttr;
    pAudioEncoder->sendPacketToAo = AENC_SendPacketToAo;
    pAudioEncoder->putAudioRawData = AENC_PutAudioRawData;
    pAudioEncoder->getSpecificInfo = AENC_GetSpecificInfo;

    *ppAudioEncoder = &pAencCtl->audioEncoder;

#if 0
    if(pAencDesc->stream == 1)
    {
        pthread_t audioThd;
        ret = pthread_create(&audioThd, 0, AudioTestPutThd, pAencCtl);
        if (ret)
        {
            LOG_PrintError("can't create thread: %s\n", strerror(ret));
            return -1;
        }

        ret = pthread_create(&audioThd, 0, AudioTestGetThd, pAencCtl);
        if (ret)
        {
            LOG_PrintError("can't create thread: %s\n", strerror(ret));
            return -1;
        }

    }
#endif

    LOG_PrintInfo("Channel:%d createAudioEncoder success!\n", pAencCtl->aencChn);
    
    goto mutex_unlock;
    
free_ctl: 
    free(pAencCtl);
    
mutex_unlock:
    pthread_mutex_unlock(&audioCtl_g.audioMutex);
    return ret;
}
